﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace com.uplus.common
{
    /// <summary>
    /// Ini文件管理类
    /// </summary>
    public class IniMgr
    {
        #region 配置文件路径
        string _content;
        string _path;
        /// <summary>
        /// 获取配置文件路径
        /// </summary>
        public string Path
        {
            get
            {

                return this._path;
            }
        }
        #endregion

        #region 保存
        /// <summary>
        /// 在原位置上保存
        /// </summary>
        public void Save()
        {
            this.Save(this.Path);
        }

        /// <summary>
        /// 保存到指定位置上
        /// </summary>
        /// <param name="path">如: D:\cfg.ini</param>
        public void Save(string path)
        {
            if (string.IsNullOrEmpty(path)) throw new Exception("目标文件不能为空");

            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<string, Dictionary<string, string>> group in this.Groups)
            {
                sb.AppendFormat("\r\n[{0}]\r\n", group.Key == "" ? "null" : group.Key);

                foreach (KeyValuePair<string, string> item in group.Value)
                {
                    sb.AppendFormat("{0}={1}\r\n", item.Key, item.Value);
                }
            }
            File.WriteAllText(path, sb.ToString());
        }
        #endregion

        public IniMgr() { }
        public IniMgr(string file)
        {
            if (!File.Exists(file))
            {
                File.AppendAllText(file, "");
            }
            this._path = file;
        }

        public IniMgr(string file, string content)
        {
            if (!File.Exists(file))
            {
                File.AppendAllText(file, "");
            }
            this._path = file;
            this._content = content;
        }

        #region ==== 单组情况 ====
        /// <summary>
        /// 获取第一个分类的键值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string this[string key]
        {
            get
            {
                return this.Items.ContainsKey(key) ? Items[key] : null;
            }
            set
            {
                this.Items[key] = value;
            }
        }

        #region 对应键值
        /// <summary>
        /// 获取第一组的对应键值
        /// </summary>
        public Dictionary<string, string> Items
        {
            get
            {
                foreach (KeyValuePair<string, Dictionary<string, string>> item in this.Groups) return item.Value;
                return new Dictionary<string, string>();
            }
        }
        #endregion

        #region 比较键值
        /// <summary>
        /// 比较第一组的键值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool KeyHasValue(string key, string value)
        {
            return this.Items.ContainsKey(key) && this.Items[key] == value;
        }
        #endregion

        #region 添加/更新键值
        public void AddItem(string key, string value)
        {
            if (this.Items.ContainsKey(key)) this.Items[key] = value;
            else this.Items.Add(key, value);
        }
        #endregion

        #region 移除键值
        public void RemoveItem(string key)
        {
            if (this.Items.ContainsKey(key)) this.Items.Remove(key);
        }
        #endregion

        #region 获取键值
        public T GetValue<T>(string key, T defaultValue)
        {
            if (this.Items.ContainsKey(key)) return (T)Convert.ChangeType(Items[key], typeof(T));
            else return defaultValue;
        }
        #endregion

        #endregion

        #region ==== 多组情况 ====

        public string this[string groupName, string key]
        {
            get
            {
                if (this.Groups.ContainsKey(groupName) && this.Groups[groupName].ContainsKey(key)) return this.Groups[groupName][key];
                return null;
            }
            set
            {
                this.AddItem(groupName, key, value);
            }
        }

        #region 对应组键值
        Dictionary<string, Dictionary<string, string>> _groups;
        public Dictionary<string, Dictionary<string, string>> Groups
        {
            get
            {
                if (_groups == null)
                {
                    _groups = new Dictionary<string, Dictionary<string, string>>();
                    string groupName = "";
                    if (string.IsNullOrEmpty(this._content))
                    {
                        this._content = File.ReadAllText(this._path);
                    }

                    foreach (string item in this._content.Replace("\r\n", "\r").Split('\r'))
                    {
                        if (string.IsNullOrEmpty(item)) continue;

                        if (item.StartsWith("["))
                        {
                            groupName = item.Replace("[", "").Replace("]", "");
                            if (_groups.ContainsKey(groupName)) throw new Exception(string.Format("配置文件{0}的组名{1}重复", _path, groupName));

                            _groups.Add(groupName, new Dictionary<string, string>());
                        }
                        else
                        {
                            int i = item.IndexOf('=');
                            if (i < 0) continue;

                            string name = item.Substring(0, i);
                            string value = item.Substring(i + 1);

                            if (_groups.Count == 0) // 只有一个分组
                                _groups.Add("", new Dictionary<string, string>());

                            _groups[groupName].Add(name, value);
                        }
                    }
                    if (_groups.Count == 0) _groups.Add("", new Dictionary<string, string>());
                }
                return _groups;
            }
        }
        #endregion

        #region 比较组键值
        public bool KeyHasValue(string groupName, string key, string value)
        {
            return this.Groups.ContainsKey(groupName) && this.Groups[groupName].ContainsKey(key) && this.Groups[groupName][key] == value;
        }
        #endregion

        #region 添加组
        /// <summary>
        /// 添加空组(若已存在则不添加)
        /// </summary>
        /// <param name="name">组名</param>
        public void AddGroup(string name)
        {
            this.AddGroup(name, new Dictionary<string, string>());
        }

        /// <summary>
        /// 添加组(若已存在则不添加)
        /// </summary>
        /// <param name="name">组名</param>
        /// <param name="values">键值</param>
        public void AddGroup(string name, Dictionary<string, string> values)
        {
            if (this.Groups.ContainsKey(name)) return;
            if (values == null) values = new Dictionary<string, string>();

            Groups.Add(name, values);
        }
        #endregion

        #region 移除组
        public void RemoveGroup(string groupName)
        {
            if (groupName != null && this.Groups.ContainsKey(groupName)) this.Groups.Remove(groupName);
        }
        #endregion

        #region 添加组键值
        public void AddItem(string groupName, string key, string value)
        {
            if (!this.Groups.ContainsKey(groupName)) this.AddGroup(groupName);

            if (this.Groups[groupName].ContainsKey(key)) this.Groups[groupName][key] = value;
            else this.Groups[groupName].Add(key, value);
        }
        #endregion

        #region 移除组键值
        public void RemoveItem(string groupName, string key)
        {
            if (this.Groups.ContainsKey(groupName) && this.Groups[groupName].ContainsKey(key)) this.Groups[groupName].Remove(key);
        }
        #endregion

        #region 获取键值
        public T GetValue<T>(string groupName, string key, T defaultValue)
        {
            if (this.Groups.ContainsKey(groupName) && this.Groups[groupName].ContainsKey(key)) return (T)Convert.ChangeType(this.Groups[groupName][key], typeof(T));
            return defaultValue;
        }
        #endregion

        #endregion
    }
}
